package com.monster.datasourcejob.tablebuildingsql.sqlconverter.impl;

import com.monster.datasourcejob.model.Field;
import com.monster.datasourcejob.tablebuildingsql.generator.impl.HiveTableBuildingSqlGenerator;
import com.monster.datasourcejob.tablebuildingsql.parser.impl.MysqlTableBuildingSqlParser;
import com.monster.datasourcejob.tablebuildingsql.sqlconverter.TableBuildingSqlConverter;
import com.monster.datasourcejob.typeconverter.impl.Mysql2HiveTypeConverter;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * description:
 * mysql建表语句转化为hive建表语句
 * @author Yuanml on 2021/6/29 17:27
 */
public class Mysql2HiveTableBuildingSqlConverter implements TableBuildingSqlConverter {
    /**
     * 表名称，未传入时将从mysql建表语句中解析
     */
    private String tableName;
    /**
     * hive数据分隔符，未传入时默认为\001
     */
    private String terminatedField = "\\001";
    /**
     * 表注释，未传入时将从mysql建表语句中解析
     */
    private String tableComment;
    /**
     * 数据库名称，未传入时将为空字符串
     */
    private String dbName;

    /**
     * hive分区字段，未传入时表示不是分区表
     */
    List<Field> partitionFields;

    public Mysql2HiveTableBuildingSqlConverter() {
    }

    public Mysql2HiveTableBuildingSqlConverter(String tableName, String terminatedField, String tableComment, String dbName, List<Field> partitionFields) {
        this.tableName = tableName;
        this.terminatedField = terminatedField;
        this.tableComment = tableComment;
        this.dbName = dbName;
        this.partitionFields = partitionFields;
    }

    @Override
    public String convert(String mysqlTableBuildingSql) {
        MysqlTableBuildingSqlParser mysqlTableBuildingSqlParser = new MysqlTableBuildingSqlParser(mysqlTableBuildingSql);
        // 从mysql建表sql解析字段信息
        List<Field> fieldsFromMysql = mysqlTableBuildingSqlParser.getFields();
        if (StringUtils.isBlank(this.tableName)) {
            this.tableName = mysqlTableBuildingSqlParser.getTableName();
        }
        if (StringUtils.isBlank(this.tableComment)) {
            this.tableComment = mysqlTableBuildingSqlParser.getTableComment();
        }

        return genHiveTableBuildingSql(fieldsFromMysql);
    }

    /**
     * description:
     * 生成hive建表语句
     * @param fieldsFromMysql   从mysql建表语句中解析出来的字段信息
     * @return                  返回mysql建表语句对应的hive建表语句
     * @author Yuanml
     * @date 2021/6/29 18:02
     **/
    private String genHiveTableBuildingSql(List<Field> fieldsFromMysql) {
        // 字段类型转换
        for (Field field : fieldsFromMysql) {
            field.setType(Mysql2HiveTypeConverter.INSTANCE.convert(field.getType()));
        }
        // 生成hive建表sql
        HiveTableBuildingSqlGenerator.HiveTableSqlCreatorBuilder hiveTableSqlCreatorBuilder = new HiveTableBuildingSqlGenerator.HiveTableSqlCreatorBuilder();
        if (partitionFields != null && partitionFields.size() > 0) {
            hiveTableSqlCreatorBuilder.partitionFields(partitionFields);
        }
        HiveTableBuildingSqlGenerator hiveTableSqlCreator =
                hiveTableSqlCreatorBuilder
                        .fields(fieldsFromMysql)
                        .tableName(tableName)
                        .terminatedField(terminatedField)
                        .comment(tableComment)
                        .dbName(dbName)
                        .build();
        return hiveTableSqlCreator.sqlForCreateTable();
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTerminatedField() {
        return terminatedField;
    }

    public void setTerminatedField(String terminatedField) {
        this.terminatedField = terminatedField;
    }

    public String getTableComment() {
        return tableComment;
    }

    public void setTableComment(String tableComment) {
        this.tableComment = tableComment;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    public List<Field> getPartitionFields() {
        return partitionFields;
    }

    public void setPartitionFields(List<Field> partitionFields) {
        this.partitionFields = partitionFields;
    }
}
